home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-03-01 | 77.0 KB | 2,036 lines |
- Newsgroups: comp.sources.unix
- From: madler@cco.caltech.edu (Mark Adler)
- Subject: v25i146: zip - file compression/archive tool, Part05/07
- Sender: unix-sources-moderator@pa.dec.com
- Approved: vixie@pa.dec.com
-
- Submitted-By: madler@cco.caltech.edu (Mark Adler)
- Posting-Number: Volume 25, Issue 146
- Archive-Name: zip/part05
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 5 (of 7)."
- # Contents: history ship.c
- # Wrapped by vixie@cognition.pa.dec.com on Sun Mar 1 18:57:38 1992
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'history' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'history'\"
- else
- echo shar: Extracting \"'history'\" \(36825 characters\)
- sed "s/^X//" >'history' <<'END_OF_FILE'
- Note, this history contains mail addresses and ftp locations that no longer
- exist, such as addresses at wsmr-simtel20 and directory names containing
- w8sdz, among others. For problems, the correct email address is
- zip-bugs@cs.ucla.edu.
- X
- X------------------------ Nov 7 1990 version 0.0 ------------------------
- X------------------------ Nov 8 1990 version 0.1 ------------------------
- X------------------------ Nov 12 1990 version 0.2 ------------------------
- X------------------------ Nov 14 1990 version 0.3 ------------------------
- Thank you for your comments. Here is Zip 0.3 with almost all of that fixed.
- The changes include:
- X
- X1. Put \n\ for newlines in long strings (everyone had this problem).
- X2. Wrote my own bsearch (called search---different args).
- X3. Wrote my own timelocal (called invlocal), used whether STDC or not.
- X (Note to Greg: look at the code---I found a simple way to do it.)
- X4. -m now deletes empty directories also.
- X5. Changed crc.c to util.c and put search() in util.c.
- X6. Changed "void *" to "voidp *" and made voidp void for STDC, else char.
- X7. Removed -a option.
- X8. Some minor changes to zip.doc.
- X
- I did not do anything about Cliff Manis's problem with DIR not being
- defined. DIR should have been defined in sys/dir.h. If it wasn't, then
- there's something wrong with dir.h, or it is missing, or the opendir, etc.
- functions are missing. I don't really want to think about what to do for
- the latter possibility.
- X
- NUnzip 3.99 does not appear to be Unix-ready. It fails for file names longer
- than 12 characters (Segmentation fault), cannot find explicit names that
- do not contain a dot, and does not notice the Unix identifier (which should
- switch off name to lower-case mapping).
- X
- X------------------------ Nov 20 1990 version 0.4 ------------------------
- Yo Zippers,
- X
- Here is a first attempt at a Zip intended to work on System V. Try using
- X"make sysv" for such systems. I also included replacements for memset()
- and memcmp() by Bill Davidsen and James Dugal for systems without those.
- Use "make old" to include those routines. Sun's use getdents() like Sys V,
- even though it's BSD, so use "make sun". For others, try just "make".
- X
- When using "make" a second time with a different request, it's best to erase
- all the .o files to force recompiling everything.
- X
- What follows are the changes I made and some things to try if you get it
- compiled. Have fun.
- X
- Mark
- X
- X
- Changes from Zip 0.3 to Zip 0.4:
- X
- X1. Changed third arg of search() to size_t to make lint happier.
- X2. Replaced zip.doc with a man page, zip.1 (raw) and zip.man (formatted).
- X3. rename() replaced with link() and unlink().
- X4. Fixed vem in central header and added REVISION and REVDATE #define's
- X to zip.h. (Didn't read Phil's appnote.txt carefully enough there.)
- X5. Removed prototypes except for development host (NeXT). (They're only
- X there for my benefit anyway---they should not affect the resulting
- X code. Consider them some meager documentation.)
- X6. Changed rindex() to strrchr().
- X7. Improved behavior on a write failure when -b is used.
- X8. Added Bill Davidsen's and James Dugal's memset(), memcpy(), and
- X memcmp() routines under the trusty ZMEM #define.
- X9. Check that zip file is writeable before doing any real work.
- X10. Added #ifdef REGEX to use regcmp(), regex() instead of re_comp(),
- X re_exec(). (We'll see if this works.)
- X11. Replaced opendir(), readdir(), closedir() with my own opend(), readd(),
- X and closed() routines that use getdirentries() on BSD and getdents() on
- X System V (I hope) and Sun's. An #ifdef DIRENT selects getdents().
- X12. zip.h no longer #includes string.h, instead defining the string
- X functions used explicitly.
- X
- X
- If you get Zip 0.4 to compile, here are some things to test:
- X
- X1. Try zipping up some stuff, of course. Use all the options that are
- X implemented. Especially try -rp and -rpm on a directory tree (use
- X *test* files and directories, of course).
- X2. Naturally check with unzip -t, but also check with "zip xxx" where
- X xxx.zip is the zip file. This should say "nothing to do", but if it
- X says "error in zip file structure", there's a problem.
- X3. After zipping, check that there are no $Z* files leftover.
- X4. Try using -b, specifying a path on another device. Check for $Z*'s.
- X5. Try -d and a regular expression (like \*.o) on a zip file.
- X6. And I'm interested in timing---try it on a 500K or so text file.
- X
- X------------------------ Nov 27 1990 version 0.5 ------------------------
- Hail fellow zippers,
- X
- Here's Zip 0.5. The biggie is it now includes implosion, courtesy of Rich
- Wales. Even as we speak, he is working on new algorithms for implode that
- promise to be significantly faster. He might even get a paper out of it ...
- X
- You can use the -s option (shrink only) when testing to save a little time,
- but also try it normally to test implosion (if you test with text files
- of reasonable length, implosion will be chosen for most of them). Also, for
- speed testing of implosion, use -i to not waste time trying to shrink.
- X
- Including implosion about doubles the size of zipnn.tar.Z, so I would like
- some input on distributing subsequent versions. Would y'all like to keep
- on getting the uuencoded version via mail, or would you prefer a notice
- about availability via anonymous ftp on simtel20.army.mil in <w8sdz.zip>?
- X(I have been sending the previous versions to Keith to put there, and will
- continue to do so. I do not know what the lag time is for him to move it
- there.)
- X
- The other important change is that this is another attempt at getting the
- directory access routines working on all systems. Read the installation
- part of the manual page (zip.man). And if you feel like, read the whole
- thing. I'm also taking suggestions for and bugs in the documentation.
- X
- The differences from Zip 0.4 include:
- X
- X1. Changed all occurences of "size_t" to "extent" and typedef'ed extent
- X to size_t (after an #include <stddef.h>) for ANSI C, or unsigned int
- X otherwise. If anyone finds that they have a non ANSI C, that size_t
- X is defined, and that it is not the size of the compiler's int, then
- X please let me know.
- X2. Changed help() to put the help text in a static array of strings and
- X then printf() for each line. Some compilers barfed on the long
- X string. Suggested by davidsen@crdos1.crd.ge.com.
- X3. Added Rich Wales' implode routines, made their inclusion the default
- X (changed #ifdef IMPLODE to #ifndef NOIMPLODE).
- X4. Put "extern int errno;" in unixfile.c (redundant extern's should be ok).
- X5. Minor changes to the man page (zip.1 and zip.man).
- X6. Added warnings for names given on the command line that are not matched.
- X Lack pointed out by grimesg@sj.ATE.SLB.COM (George).
- X7. Changed back to opendir(), etc. on BSD systems.
- X8. Added NDIR #define for HPUX to #include <ndir.h> instead of <sys/dir.h>.
- X9. Redid Makefile, adding next (use shared library), sysvpw (System V's
- X that require linking the libPW library for regex routines), and hpux
- X (see #8 above).
- X
- As usual, report problems to info-zip@wsmr-simtel20.army.mil. If you wish,
- you can, in addition, send the same report to me (madler@piglet.caltech.edu)
- or Rich (wales@cs.ucla.edu) if the problem is with implosion (i* files) for
- quicker reponse.
- X
- your humble servant,
- Mark Adler
- X------------------------ Dec 7 1990 version 0.6 ------------------------
- Greetings and Felicitations Honorable Zip Compatriots,
- X
- I have uploaded Zip 0.6, which incorporates most of your helpful comments,
- to Simtel20.Army.Mil, and it should evenually end up in <W8SDZ.ZIP> as
- ZIP06.TAR-Z. The most significant change is the addition of encryption
- both as the -e option in Zip, and a new program, ZipCloak, that encrypts
- and decrypts zip entries. This surely adds some new portability problems,
- due to the getp() routine which reads a password from the terminal with no
- echoing. We'll see how well this flies ...
- X
- If someone wants to PKZIP up the tar.Z file, please do so. I didn't zip
- it up myself because a) I'm lazy, and b) PKZIP can compress it better
- anyhow, and I don't have a PC.
- X
- Also, there is an EXPORT symbol used to remove encryption, so I can make
- an export version that does not have -e or ZipCloak. This version will
- simply be missing a few source files and have a different Makefile.
- X
- I also added a few systems to the Makefile, and made some other changes to
- it based on all your detailed comments. If it still works after all that,
- I'll be amazed.
- X
- Those and other changes from 0.5 to 0.6 are detailed at the end of this note.
- X
- I have not addressed the portability problem with the implode routines,
- since that is Rich's domain. I have no idea what is causing it. (For those
- who don't know, one system produced remarkable 90% compression rates with
- implode, but alas, it is a bug.)
- X
- One fellow complained that zipping up the README file results in a zip file
- that is larger than the original, even though Zip claims it compressed it.
- Well, it did compress it, but the ZIP file format has an overhead of
- X76+2*N bytes per file+22 bytes, where N is the length of the file name.
- And that's without comments or "extra" information. So, a zip file with a
- single file whose name has six characters has an overhead of 110 bytes.
- README gets shrunk by 16% from 274 bytes to 230 bytes, resulting in a total
- zip file size of 340 bytes---larger than the original file (274 bytes).
- The moral is don't expect zip to compress a single small file. The other
- moral is use unzip -v to see the compression.
- X
- Someone else asked about multi-disk zip files. I'm not sure I believe in
- those, since PKZIP and PKUNZIP do not appear to suppport them (though it is
- part of the ZIP file definition in APPNOTE.TXT). What I was planning on
- doing for that case was to write a ZipSplit program that would take a large
- zip file and try to optimally split it into the fewest number of zip files
- that are all less than the specified size. Each would be a complete, stand
- alone zip file---not part of a single, multi-disk zip file. There would
- also be a ZipMerge program.
- X
- This is the version of Zip that will live in infamy (note the revision date).
- Of course, some current Presidents of the United States think that should be
- September 7th, but I won't name any names.
- X
- I am going on vacation for about two weeks, so I expect to find many new
- problems reported upon my return.
- X
- And lastly, for my Holiday Greetings: Party On Dudes.
- X
- Mark Adler
- madler@piglet.caltech.edu
- X
- X
- Here are the changes from Zip 0.5 to Zip 0.6:
- X
- X1. Minor documentation changes (zip.1 and zip.man).
- X2. Fixed an embarrasing lack of recursion in opend/readd/closed functions
- X that only existed in 0.5.
- X3. Moved $(LDFLAGS) to end of the linking command line in Makefile.
- X4. Added make dnix for DNIX 5.2, 5.3 not using optimization (no -O).
- X5. Wrote ZipCloak for encryption and decryption.
- X6. Rich changed the output routines of implode to use zfwrite and zputc to
- X provide hooks for encryption (defined in crypt.h). Also removed
- X function prototypes unless PROTO defined.
- X7. Added encryption (-e) to Zip.
- X8. Added make pyramid (use rindex() instead of strrchr()).
- X9. Changed make to $(MAKE) and cc to $(CC) in Makefile.
- X10. Took out strip in Makefile.
- X11. Changed year from 1991 to 1990. (How'd *that* get in there? Of course,
- X it's not as bad as when I wrote a check the other day and dated it 1977.
- X I think my brain cell isn't working as well as it used to.)
- X12. Added make cray (use scc instead of cc).
- X13. Added make amdahl (use system() instead of rmdir()).
- X14. Added entry of one-line comments for added files (-c).
- X15. Put comment delimiters around name following #endif's in Rich's code.
- X
- X------------------------ Feb 13 1991 version 0.7 ------------------------
- XFellow stuck zippers,
- X
- Well folks, it's been a while since 0.6. so there have been a lot of
- changes on the way to 0.7. The exhaustive listing is below, but here are
- some highlights ...
- X
- Implode now (appears) to be PKUNZIP compatible. There were many odd
- little requirements implosed by the coding of PKUNZIP that were obtained
- from Phil Katz and associates. Now that Rich has that working, he will
- likely be working on much faster string matching routines to speed up
- implode.
- X
- User interrupts (control-C or kill) are now caught and the temporary files
- are deleted, making for a clean getaway.
- X
- Self-extracting zip files for MSDOS can now be processed, with the
- extensions zip, ZIP, exe, or EXE. This allows you to make self-extracting
- zip files for MSDOS by taking an existing one (like PKZ110.EXE) and
- deleting all the entries to get a prototype self-extracting zip file that
- can be copied and added to. Of course, you should only do this if you are
- a registered user of PKZIP. Note that if the file does not end in .zip,
- you have to give the full name.
- X
- I have relaxed some of the restrictions on zip files to allow processing
- ones with "authenticity verification" (applied by the PUTAV program that
- comes with PKZIP). Of course, the authenticity no longer checks out if
- you muck with the file, but at least you can muck with it now.
- X
- The Makefile has been considerably simplified, thanks to suggestions from
- Jean-Loup Gailly. Also, I wrote my own sh expression matcher, eliminating
- the regular expression hassles, and the REGEX symbol and -lPW options in
- the Makefile.
- X
- Many, many cosmetic changes, the most dangerous of which was turning on
- prototypes again in the hopes we can get them to work. If they cause you
- problems, record the problems (for me), and then add a -DNOPROTO to the
- appropriate line in the Makefile and try again.
- X
- This version now compiles under Microsoft C 5.1 and Turbo C++ 1.0, with
- much thanks to Jean-Loup Gailly. I say "compiles" and not "works" because
- I have not thoroughly tested it. It does work, but there may be errors in
- the port as well as errors in the design. By the latter I mean that there
- may be some disagreement over what you expect it to do and what it does,
- especially with regards to upper and lower case names and wildcard
- patterns. Also, the implode routines do not yet work under MSDOS, so the
- compilations are done using NOIMPLODE. There are two dumb batch files to
- do the compile: doturboc.bat and domsc.bat. If someone would like to
- write make files for the make utilities that come with those languages,
- please be my guest. I'm just too lazy. However, I would probably resist
- including make files that require a make utility that does not come with
- those languages, be it commercial, shareware, or free.
- X
- There are two new programs: ZipSplit and Ship. ZipSplit tries to split a
- big zip file into the smallest number of zip files less than a specified
- size. This is to aid in using zip to backup to floppies. It has the
- limitation that it cannot break up an entry in a zip file, since it makes
- complete, standalone zip files. This means if any entry is larger than
- the specified size (plus some overhead), zipsplit will give up and not do
- the split. It does *not* implement the multi-disk zip file format implied
- in APPNOTE.TXT. ZipSplit will optionally write an index file and deduct
- the size of that file from the first zip file so both will fit on the
- first disk.
- X
- Ship is a fixed-up version of a program I have been using myself for some
- time in place of uuencode/uudecode. It's purpose is to facilitate sending
- zip files through the mail. It uses a more efficient coding scheme than
- uuencode (four bytes per five characters instead of three bytes per four
- characters) and includes a crc at the end of each file to check the
- veracity what was received. It can split its output to a specified size
- and recombine it automatically at the other end, verifying the sequence.
- It can also mail the parts to a specified address, with subject lines
- identifying the parts, instead of making a bunch of files that you're just
- going to mail and delete anyway. Example:
- X
- X % ship -500 -m saddam@pickle.iq README zip07.zip
- X README shipped
- X zip07.zip shipped
- X files part0001..part0004 mailed
- X
- will mail README and zip07.zip together in four chunks of 500 or fewer
- lines each. At the other end, Saddam can save the parts into the files
- named in the subject lines (part0001..part0004), and then do:
- X
- X % ship -u part*
- X README received
- X zip07.zip received
- X
- XFor now, zip.1 (and zip.doc) are incomplete as far as MSDOS goes. I'll
- put off doing that until the MSDOS version has stabilized. Likewise, I
- have put off writing zipcloak.1, zipsplit.1, and ship.1 for the same
- reason.
- X
- There are, of course, all the little changes that fix bugs (what are
- those?), make the Makefile work on more systems, documentation, and,
- for the alert reader, an undocumented option ...
- X
- As usual, send reports to info-zip@wsmr-simtel20.army.mil, so everyone
- can get a chuckle out of whatever new bugs I've introduced.
- X
- Mark Adler
- madler@pooh.caltech.edu
- X
- X
- Changes from release 0.6 to release 0.7:
- X
- X1. Changed Makefile to use mv instead of -o on compiles.
- X2. Added MAKE = make to Makefile.
- X3. Catch user interrupt or termination and delete temporary files.
- X4. Allow general purpose flags in local and central headers to differ in
- X the "reserved" bits. Keep both for copying zip entries verbatim.
- X5. Removed prototype for closedir--return value not used and inconsistent
- X across systems.
- X6. Wrote ZipSplit to break a large zip file into the smallest number of
- X zip files less than a specified size. Run zipsplit with no arguments
- X to see the command help.
- X7. Put error messages in globals.c to be common across zip, zipcloak, and
- X zipsplit. Use #define's in zip.h for error numbers.
- X8. Changed getp() to open a new file for the terminal device, and added
- X the echon() function to turn echoing back on when interrupted at
- X password prompt.
- X9. Added warn()'s to distinguish various zip file structure errors.
- X10. Allow "extra" fields in local and central headers to differ.
- X11. Fixed percent compression calculation to work for very large files.
- X12. Included the program (makecrc.c) that generates the CRC table.
- X makecrc.c is not compiled or run by the Makefile, but is present for
- X completeness.
- X13. Added an undocumented (except for here) option, -v, to zip that checks
- X for "oddities" in the zip file structure and points them out if found
- X (but continues processing).
- X14. Put prototypes in crypt.h inside #ifdef NeXT to avoid redefinition
- X problems with other compilers.
- X15. Added "make zilog" for Zilog S8000 running Zeus 3.21.
- X16. Minor changes to the manual page (zip.1 and zip.doc).
- X17. Fixed bug in replace() (manifested by -b option).
- X18. readzipfile() now also checks the central directory start and size in
- X the end of central directory header.
- X19. Allow modification of self-extracting zip files (exe instead of zip).
- X20. Allow .ZIP as valid suffix as well as .zip (also .EXE and .exe).
- X21. Cleaned up malloc usage, free'd everything malloc'ed.
- X22. fclose'd all fopen'ed files explicitly.
- X23. Corrected assignment of one ftell() result from an int to a long.
- X24. Considerably simplified Makefile, based on Jean-Loup Gailly's
- X suggestions.
- X25. Renamed unixfile.c to fileio.c in anticipation of non-unix support.
- X26. Removed const's (pesky little buggers caused too many problems).
- X27. Wrote my own shell expression compare routine, took REGEX and -lPW's
- X out of Makefile, which removed the sysvpw make option.
- X28. Added tempname() prototype to crypt.h for the implode routines to use.
- X29. Trying string.h for prototypes of string functions if __STDC__
- X defined, which is what unzip.h does.
- X30. Turned prototypes on if __STDC__ defined (we'll try this one more
- X time). They can be turned off using NOPROTO.
- X31. Improved source documentation.
- X32. Changed prototype of open in fileio.c to OF((char *, int, ...)).
- X33. Removed "local" from prototypes of main() (after all, it's *not*
- X local).
- X34. Wrote Ship program to supplant uuencode--slightly more efficient, has
- X error checking, file splitting, automatic mailing, other features.
- X Ship currently uses the command:
- X /usr/ucb/mail -s subject < tempfile
- X to send mail. Please let me know what works for your system. Note
- X that I want to be able to specify a subject line.
- X35. Ported to MSDOS Microsoft C 5.1, based on Jean-Loup Gailly's work.
- X36. Fixed add/update bug when -p not used.
- X37. Handle lower case conversion and devices (e.g. C:) for MSDOS.
- X38. Indented the #ifdef/#ifndef constructs that do not contain function
- X definitions, to improve the readability somewhat.
- X39. Cleaned up error handling. Now use perror() for i/o errors. Put the
- X errors and messages in ziperr.h.
- X40. Ported to MSDOS Turbo C++ 1.0.
- X41. Implemented wild card expansion on the command line for MSDOS and
- X handle MSDOS matching (*.* == all, not *).
- X42. Changed version required to unzip to 11 (1.10) since the implode
- X routines can procude an overlapping match one away from the end of the
- X window (PKUNZIP 1.00 requires two away from the end).
- X43. Changed old next make option to next10 (for version 1.0) and added a
- X new next make option for 2.0 (just called next) that uses the -object
- X linking option for smaller executables.
- X44. Added -z option to take a multi-line zip file comment from stdin.
- X45. Changed temporary names from $ZXXXXXX to _ZXXXXXX, where XXXXXX is
- X filled in by mktemp(). This avoids problems with "rm $Z*" in sh.
- X46. Got new implode routines from Rich that are (hopefully) PKUNZIP
- X compatible.
- X47. When -b is not specified, put the temporary files in the same
- X directory (i.e. the same device) that the zip file is (or will be) in.
- X48. Added doturboc.bat and domsc.bat files to compile for Turbo C++ 1.0
- X and Microsoft C 5.1. I am interested in successes and failures with
- X other versions of those compilers. In this version, the implode
- X routines do not work under MSDOS.
- X------------------------ May 6 1991 version 0.8 ------------------------
- Buenos Dias Amigos,
- X
- Heer ees dee Cinco de Mayo reeleese of seep, aka Zip 0.8. The changes
- from 0.7 are in the (long) list below, but here are some highlights:
- faster implode, faster shrink, first attempt at a VMS version (thanks
- to Cave Newt), and a new program, ZipNote, to aid in editing zip file
- comments. To compile under VMS, do an "@makevms.com". To compile using
- Mircosoft C do a "make makefile.msc". To compile using Borland (Turbo)
- C, do a "make -fmakefile.bor". Please try to break any or all of these
- programs in every conceivable way--we're getting close a public release.
- Thank yew fer your support.
- X
- Mark Adler
- madler@pooh.caltech.edu
- X
- Changes from 0.7 to 0.8:
- X
- X1. Added the -n option to prevent compressing already compressed files.
- X Documented -n in zip.1.
- X2. Check the length of the compressed data in zipup() in case implode or
- X shrink has a bug.
- X3. Fixed -v option to not complain about needing PKUNZIP 1.1.
- X4. Added report of store/shrink/implode sizes when -v (verbose) used.
- X5. Put in Rich's patch to fix 100% implosion bug.
- X6. Fixed -i bug.
- X7. Made changes to im_ctree.c and implode.c to (hopefully) make it work
- X under MSDOS. (Jean-Loup said declare topmaxvals and botmaxvals as
- X U_INT in im_ctree.c, and use MSDOS, not __MSDOS__ in implode.c.)
- X8 Added implode routine compilation to domsc.bat and doturboc.bat.
- X9. Replaced FILENAME_MAX with FNMAX, which is now always 1024. (It seems
- X FILENAME_MAX is incorrectly set to 14 on some System V Unixii.)
- X10. Changed BEST to -1 so it is different from STORE (=0). Redid some of
- X the method logic in zipup().
- X11. Changed wb+ to w+b in implode.c.
- X12. Removed "nothing to do" error for -u and -f.
- X13. Zip source distributions will now have tabs removed, except for
- X Makefile and Makefile.exp (no feelthy tabs rule).
- X14. Changed zip error on open failure to a warning. This accounts for
- X files that do not have read permission or are locked, and files
- X deleted during the zip. For entries being updated, the old entry is
- X copied over instead. This change had the side effect of removing the
- X zipskip() routine.
- X15. Removed OBJC dependencies in Makefile.exp (didn't belong).
- X16. Removed strip from Makefile, instead using the -s link option.
- X17. Fixed -um and -fm to delete files whose entry's times were checked in
- X the archive.
- X18. Put portability stuff common to zip.h and crypt.h into tailor.h.
- X19. Added mark tracing to -v (for debugging).
- X20. Changed name and zname logic--an external name is always converted
- X into an internal zname, and vice-versa. zname is now always
- X malloc'ed.
- X21. Fixed -z to use CRLF between lines (for PKZIP) and have no newline
- X after the last (or only) line.
- X22. Added clean to Makefile (deletes *.o, zip, zipcloak, zipsplit, ship).
- X23. Replaced LDFLAGS with LFLAGS1 and LFLAGS2 in Makefile (splits link
- X options before and after object files as in unzip).
- X24. Added scodos to Makefile (from Bill Davidsen).
- X25. Included stdio.h in tailor.h--removed stdio.h from zip.h and
- X implode.h.
- X26. Do not include stddef.h if M_XENIX defined.
- X27. Cast the arguments of all free() calls to (voidp *).
- X28. Added casts to char * for memset() and qsort() args in zipsplit.c.
- X29. Changed implode.h to define malloc and str* properly.
- X30. Fixed invlocal() to handle integer overflow correctly, as well as
- X reliably across compilers.
- X31. Got new implode.h from Rich with fix #29 above. Removed stdio.h
- X include.
- X32. Commented out the abort() calls in im_ctree.c.
- X33. -ee requests a verification of the encryption password.
- X34. malloc and free tempath.
- X35. Documented -, SCO, and scodos in zip.1, and - in help().
- X36. Added revision.h for Zip revision number and date.
- X37. -u and -f with no arguments now (both) freshen the entire archive.
- X38. Use /Oait instead of /Ox for MSC to avoid loop optimization (buggy on
- X 5.1, and sometimes even crashes compiler!).
- X39. Added ! (reverse) range matching to shmatch(), and early abort on '*'
- X failures (speeds up pathological patterns). Cleaned up '\' (escape)
- X handling.
- X40. Changed '!' in ship to '{' (some EBCDIC translations do not include
- X !). However, unship (ship -u) still understands '!'. Also added the
- X -v option of ship to print out the version and revision date. Also
- X now refuse to overwrite an existing file when unshipping (ship -u),
- X but there is a -o option to overwrite anyway.
- X41. Added a "fast" mode to ship using hard-arithmetic coding that is
- X nearly as efficient as base 85 coding, but much faster on 16-bit
- X machines (base 85 coding uses 32 bit multiplication and division).
- X42. Put tailor.h back in ship.c, so that ship.c can stand on its own.
- X43. Made -p the default, and added a new option, -j to do the opposite
- X (junk directory names). -p is still there but does nothing, so as to
- X avoid annoying PKZIP users. Changed documentation and help()
- X accordingly.
- X44. If -j is used, and two files are to be added with the same name, then
- X zip exits with an error.
- X45. Wrote ZipNote for editing zipfile comments. Just do zipnote for
- X usage.
- X46. Replaced Rich's im_lmat.c with a new one from Jean-Loup. Improves the
- X speed of implode by a factor of two, and even more for very large
- X files.
- X47. Reduced the execution time of shrink by 33% simply by moving the code
- X around (eliminated some unnecessary calls, moved some tests).
- X Shrink's execution time is now about 50% more than compress (it used
- X to take over twice as long). Hash tables for shrink are still
- X intended for a future release.
- X48. VMS mods from Greg: replace() unlinks only after copy, changed
- X delete() to destroy(), added code for deletedir(), use creation time
- X instead of modification time, warn if stamp() attempted, changed
- X includes, make link rename and unlink delete, added findfirst,
- X findnext stuff, added wild() for VMS, modified newname(), procname().
- X49. Implemented internal<-->external name conversions for MSDOS and VMS.
- X50. For VMS matching, changed ? to %, removed bracketed ranges.
- X51. Added makevms.com, stolen from Unzip (vms_make.com).
- X52. Implemented -k (force the zip file to look like it was made by PKZIP).
- X53. Removed implode for VMS (it crashes--haven't tracked down where).
- X54. Got Jean-Loup's makefile.dos working for MSC 5.1 (makefile.msc) and
- X Turbo C++ 1.0 (makefile.bor).
- X------------------------ Jul 11 1991 version 0.9 ------------------------
- Hey gang,
- X
- Here is our very-nearly-ready-to-release version of Zip. There will be no
- features added or changed from 0.9 to 1.0--only bugs fixed. I hope that
- we can get 1.0 out pretty quickly then. This is really your last chance to
- find bugs before it goes out, so please, please test all the programs as
- much as you can. Try all the features, if possible, and perhaps try to
- think of ways to break the programs. Also, and this is very important, read
- the documentation in zip.doc and "debug" that too. I already know that it
- is not complete in 0.9, but please send any comments about errors, omissions,
- format, or whatever to Info-ZIP, even if they seem obvious.
- X
- The highlights of the changes from 0.8 to 0.9 are: faster, slicker implode;
- operation in small model on MSDOS for speed; a new temporary file interface
- for faster operation on small files; some shrink improvements; and some new
- options (-y, -g, -q). Also, ship has been enhanced in several ways, not the
- least of which is a help option (-h).
- X
- Have fun.
- X
- Mark Adler
- madler@tybalt.caltech.edu
- X
- X
- Changes from 0.8 to 0.9:
- X
- X1. Removed the "not implemented yet" note in help() for -k (it *is*
- X implemented now). Removed from bug list in zip.1 too.
- X2. Fixed Turbo C implode bug.
- X3. Added /link /e in makefile.msc for ship.c.
- X4. Made handler() in zipnote.c the same as handler() in zipsplit.c.
- X5. Added -y option in Unix to store symbolic links as such. (We need
- X Unzip to be aware of symbolic links and use symlink() to recreate them.)
- X6. Ignore control characters in unship input.
- X7. Use prototypes and ANSI libraries if MSDOS. (Used to check for Turbo C,
- X but Microsoft C 6.0 also does not define __STDC__ unless strict ANSI
- X is requested.)
- X8. Added mod to ct_fsort() from Rich that should remove any qsort()
- X dependencies in implode output.
- X9. Removed some 32/16-bit prejudices in util.c and crypt.c that affect
- X 64-bit integer (short, int, and long) machines (Cray).
- X10. Added System V MAILX option to ship.c to use the mailx command. This
- X is automatically activated by DIRENT if ship is compiled by the zip
- X makefile.
- X11. Added patches from Greg Roelofs for echo control on Cray and Amdahl.
- X The patch uses termio.h and ioctl(), and is assumed for all System V,
- X not just those (we'll see how this flies).
- X12. Changed -Ox to -Oacegit -FPi87 in makefile.msc. Added /nologo to link.
- X13. Applied J-L's 082 mods (Sinatra style): select 4K window for < 5.5K,
- X 8K window for >= 5.5K files (just like PK does); various im_ctree.c
- X mods verbatim (except for the treename warning, which I did differently);
- X various im_lmat.c mods verbatim (except macros are done the ugly portable
- X way); farmalloc'ed in shrink.c; changed makefile.msc and makefile.bor to
- X use small model; added J-L to zip.1 acknowledgements (oops).
- X14. Moved struct zlist's and struct flist's to far storage (needed by above
- X mods). Unfortunately, I can't move the names and other things pointed to
- X by those structures into the far space, since they are arguments to
- X library functions like strcmp() and fwrite().
- X15. Changed zipup() to both shrink and implode only on files smaller than
- X BSZ. Also in that case, free up shrink data structures before allocating
- X the implode data structures. Changed from fopen() to open() except for
- X VMS.
- X16. Fixed bug in dosmatch() to free malloc'ed space.
- X17. MINIX mods (do not need minix make option): call tempname() with a unique
- X character (MINIX mktemp() flawed); defined S_IWRITE as S_IWUSR if S_IWUSR
- X defined; removed explicit signal dereference.
- X18. Fixed bug in unship when used as a filter with no args.
- X19. Changed getnam() to not use static storage.
- X20. Copy permissions from old to new zip file (zip, zipcloak, zipnote).
- X21. Added patches for AT&T 3B1, added 3b1 target to makefile, added to zip.1.
- X22. Made FNMAX 256 for MSDOS (is 1024 otherwise).
- X23. Used the "pyr" predefined symbol for Pyramid systems in tailor.h.
- X24. Added Greg's VMS mods to ship.c. Added help to ship.c (-h or -?).
- X Changed meaning of -nnn arg from lines to K.
- X25. Moved ZMEM routines to fileio.c to properly include them in zipnote and
- X zipsplit.
- X26. Added -s option to ship to specify a subject line prefix.
- X27. Fixed -z in zip to not trash leading blank lines in the comment.
- X28. Made ship recognize "unship" in argv[0] a little more flexibly.
- X29. Made sure temporary zip files are closed before being deleted by an
- X error or interrupt.
- X30. Added a new temporary file interface and new source files tempf.c and
- X tempf.h. This avoids making temporary files for small (<16k) output.
- X Both shrink and implode use this.
- X31. Added OS/2 patches, files. However, left zip case-sensitive for OS/2
- X names, as in Unix.
- X32. Removed amdahl target in makefile, using UTS symbol instead.
- X33. Changed -y to depend on definition of S_IFLNK.
- X34. Avoid leading periods on lines in ship output by inserting a space.
- X35. Ship is now extensible: added a warning for "unsupported keyword".
- X Such keywords can appear before the "ship" line, for example.
- X36. Added -g option to allow "growing" the zip file. If just adding new
- X entries to a zip file, -g will write over the old zip file without
- X creating a temporary. The danger is that if there is an error, the
- X old zip file will be lost. If not just adding, then -g is ignored.
- X37. Added aux (A/UX) target to makefile.
- X38. In shrink.c, removed unnecessary FreeList and ClearList arrays, and
- X the recursive Prune() routine. This also resulted in a speedup in
- X shrink of about 15%. It is now only about 30% slower than Unix compress.
- X39. Added -q option for quiet operation.
- X------------------------ Sep 21 1991 version 1.0 ------------------------
- Hello world!
- X
- This is the first public release version of Zip and its cohort utilities.
- We hope you enjoy using it much much more than we enjoyed writing it and
- trying to get it to work on every fritzing raffing bliffing nobbin Unix
- system in the galaxy.
- X
- Please feel free to send any problems, complaints, suggestions, kudos,
- ridicule, or whatever to zip-bugs@cs.ucla.edu. If there were a way to
- send cookies over the net, we'd accept those too.
- X
- Thank yew fer yur support.
- X
- Mark Adler
- madler@tybalt.caltech.edu
- X
- X
- Changes from 0.9 to 1.0:
- X
- X1. Removed some pesky carriage returns masquerading as spaces in fileio.c
- X and zipup.c.
- X2. Removed #include memory.h in tempf.c (string.h good enough).
- X3. Compile ship in doturboc.bat.
- X4. Miscellaneous zip.1 (zip.doc) changes.
- X5. Fixed mistake in stamp() in fileio.c (didn't double seconds).
- X6. Applied Jean-Loup's mods for Cray's (do not assume 16-bit shorts).
- X7. Removed pyramid make option, since #ifdef pyr seems to work.
- X8. Added some casts to tempf.c to clean up some warnings.
- X9. Added comment to makefile.exp saying what it is.
- X10. Removed length checks in zipup.c to fix problem with using Vax variable
- X record length formats.
- X11. Fixed VMS replace-across-devices problem.
- X12. Changed order of include's in implode.h to make tailor.h show up first.
- X13. Added Convex mods and make target.
- X14. Fixed path delimiter under VMS for unship.
- X15. Added ship to makevms.com.
- X16. Put in new copyright messages.
- X17. Added aix make target.
- X18. Fixed zipsplit.idx to start counting at one like the file names.
- X19. Changed -a (append VMS version number) to -w to leave -a open for a
- X possible future option.
- X20. Back to separate makefiles for Microsoft and Borland (.msc and .bor).
- X21. Workaround in fileio.c for Borland stat() bug: stat() succeeds for wild
- X card names that match existing files.
- X22. Added "(did you remember to use binary mode when you transferred it?)"
- X to the "probably not a zip file" warning.
- X23. Changed utilities to append .zip only when the zip file name does not
- X contain a dot.
- X24. At least mentioned the other utilities in zip.doc (zipcloak, ship, etc.),
- X and documented upper case matching of names when using -d under MSDOS.
- X25. Fixed bug in MSDOS version: zip foo c:autoexec.bat wouldn't work.
- X26. Added hidden/system attribute bug to BUGS in zip.1
- X27. Fixed recognition of unship in ship when unship is in a path.
- X28. Added non-stream-LF VMS bug to zip.1 bug list.
- X29. Fixed bug in #23 above when path has dots. Documented #23 in zip.1.
- X30. Show disclaimer only for -l, add -h and -l to zip utilities.
- X31. Applied Minix patches.
- END_OF_FILE
- if test 36825 -ne `wc -c <'history'`; then
- echo shar: \"'history'\" unpacked with wrong size!
- fi
- # end of 'history'
- fi
- if test -f 'ship.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'ship.c'\"
- else
- echo shar: Extracting \"'ship.c'\" \(38393 characters\)
- sed "s/^X//" >'ship.c' <<'END_OF_FILE'
- X/* ship.c -- Not copyrighted 1991 Mark Adler */
- X
- X#define SHIPVER "ship version 1.0 September 29, 1991 Mark Adler"
- X
- X/* Command for mailing (-m): the %s's are, in order, the subject prefix,
- X the part number (always of the form "partnnnn"), the subject suffix
- X (empty or " (last)" if the last part), the mailing address, and the
- X name of the temporary file begin mailed. The command "Mail" is for BSD
- X systems. You may need to change it to "mailx" for System V Unix, using
- X the compile option "-DMAILX". Also, on Sperry (Unisys?) SysV.3 systems,
- X you might try the command name "v6mail". */
- X
- X#ifdef DIRENT /* If compiled with zip, DIRENT implies System V */
- X# define MAILX
- X#endif /* DIRENT */
- X
- X#ifdef sun /* Except Sun's use DIRENT, but have Mail */
- X# ifdef MAILX
- X# undef MAILX
- X# endif /* MAILX */
- X#endif /* sun */
- X
- X#ifdef sgi /* Silicon Graphics that way too */
- X# ifdef MAILX
- X# undef MAILX
- X# endif /* MAILX */
- X#endif /* sgi */
- X
- X#ifdef VMS
- X# define TMPNAME "_SXXXXXX."
- X# define MAILCMD "mail %s /subj=\"%s %s%s\" \"%s\""
- X# define PATHCUT ']'
- X#else /* !VMS */
- X# define TMPNAME "_SXXXXXX"
- X# ifdef MAILX
- X# define MAILCMD "mailx -s \"%s %s%s\" \"%s\" < %s"
- X# else /* !MAILX */
- X# define MAILCMD "Mail -s \"%s %s%s\" \"%s\" < %s"
- X# endif /* ?MAILX */
- X# define PATHCUT '/'
- X#endif /* ?VMS */
- X
- X/*
- X
- SHIP -
- X
- X Ship is a program for sending binary files through email. It is designed
- X to supplant uuencode and uudecode. Ship encodes approximately 6.23 bits
- X per character mailed, compared to uuencode's 5.73 bits per character.
- X
- X Ship also has these features: a 32-bit CRC check on each file; automatic
- X splitting of the ship output into multiple, smaller files for speedier
- X mailing; automatic mailing of ship's output, with subject lines for
- X multiple parts; and a check on the sequence of parts when unshipping.
- X
- X Usage:
- X
- X ship [-nnn] [-m address] [-s subject] file ...
- X
- X where nnn is the maximum number of K bytes for each output file, address
- X is the address to send mail to, subject is a Subject" line prefix, and
- X file ... is a list of files to ship. If no options are given, ship
- X outputs to stdout. The simplest use is:
- X
- X ship foo > x
- X
- X where foo is converted into the mailable file, x.
- X
- X When -nnn is specified, but -m is not, ship writes to the files
- X part0001, part0002, etc., where each file has nnn or less K bytes. For
- X example:
- X
- X ship -25 bigfoo
- X
- X will write however many 25K byte or less ship files is needed to contain
- X bigfoo. If, say, six files are needed, then the files part0001 to part0006
- X will be written.
- X
- X When using -m, nothing is written, either to files or to stdout; rather,
- X the output is mailed to the specified address. If -nnn is also specified,
- X then the parts are mailed separately with the subject lines part0001, etc.
- X If -nnn is not specified, then only one part (the whole thing) is mailed
- X with the subject line "part0001". For example:
- X
- X ship -25 -m fred bigfoo
- X
- X will mail the six parts of bigfoo to fred.
- X
- X Any number of files can be shipped at once. They become part of one long
- X ship stream, so if, for example -25 is specified, all but the last part
- X will have about 25K bytes. For example:
- X
- X ship -25 -m fred fee fi fo fum
- X
- X will send the files fee, fi, fo, and fum to fred.
- X
- X Fred will get several mail messages with the subject lines part0001, etc.
- X He can then save those messages as the files, say, p1, p2, p3, ...
- X Then he can use the command:
- X
- X ship -u p?
- X
- X to recreate bigfoo, or fee fi fo and fum, depending on what he was sent.
- X If Fred saved the wrong numbers, ship will detect this and report a
- X sequence error.
- X
- X Note: there is enough information in the shipped parts to determine the
- X correct sequence. A future version of ship will prescan the files to
- X determine the sequence, and then process them in the correct order.
- X
- X If a file being received already exists, ship -u will report an error
- X and exit. The -o option avoids this and allows ship to overwrite existing
- X files. The -o option must follow the -u option:
- X
- X ship -u -o p?
- X
- X In addition to the -u option, ship will unship if it sees that its name is
- X unship. On Unix systems, this can be done simply by linking the executable
- X to unship:
- X
- X ln ship unship
- X
- X Ship can also be used as a filter. The special file name "-" means stdin.
- X For example:
- X
- X tar covf - foodir | compress | ship -25 -m fred -
- X
- X will tar the directory foodir, compress it, and ship it to fred in 25K byte
- X pieces. Then, after Fred saves the files as p01, etc. at the other, end,
- X he can:
- X
- X ship -u p? | zcat | tar xovf -
- X
- X which will recreate the directory foobar and its contents. ship -u knows
- X to write to stdout, since the original ship put the special file name "-"
- X in the first part.
- X
- X Ship uses a base 85 coding that needs 32-bit multiplication and division.
- X This can be slow on 16-bit machines, so ship provides a fast encoding
- X method by specifying the -f option. This method is somewhat faster even
- X on 32-bit machines, and has approximately a 1% penalty in the size of the
- X encoded result (-f gives 6.26 bits per character, on the average). The -f
- X option need only be used when shipping--unshipping (ship -u) automatically
- X detects the encoding used. For example:
- X
- X ship -f -25 -m fred foo
- X
- X will send foo to fred in 25K byte pieces using the fast encoding method.
- X You don't need to tell Fred, since ship -u will figure that out for him.
- X
- X The fast encoding method is probabilistic, so it's possible for the size
- X penalty to be worse than 1%, and it's also possible for the fast encoding
- X to produce a smaller result than base 85 encoding would, all depending on
- X the data.
- X
- X The -q option can be used with either ship or unship (ship -u) for quiet
- X operation--informational messages are inhibited.
- X
- X You can find out the version of ship and get the command usage by using
- X "ship -h" or "ship -?". The version number and date and help will be
- X printed, and ship will exit (the rest of the command line is ignored).
- X
- X Acknowledgements:
- X
- X The hard-arithmetic coding algorithm was blatantly stolen from Peter
- X Gutmann's pgencode/pgdecode programs posted on comp.compression, with
- X modifications to use 86 instead of 94 characters, and to make zeros encode
- X better than, rather than worse than other bytes. (As Stravinsky once said:
- X "Mediocre composers plagiarize. Great composers steal.")
- X
- X*/
- X
- X/* tailor.h -- Not copyrighted 1991 Mark Adler */
- X
- X/* const's are inconsistently used across ANSI libraries--kill for all
- X header files. */
- X#define const
- X
- X
- X/* Use prototypes and ANSI libraries if __STDC__ */
- X#ifdef __STDC__
- X# ifndef PROTO
- X# define PROTO
- X# endif /* !PROTO */
- X# define MODERN
- X#endif /* __STDC__ */
- X
- X
- X/* Use prototypes and ANSI libraries if Silicon Graphics */
- X#ifdef sgi
- X# ifndef PROTO
- X# define PROTO
- X# endif /* !PROTO */
- X# define MODERN
- X#endif /* sgi */
- X
- X
- X/* Define MSDOS for Turbo C as well as Microsoft C */
- X#ifdef __POWERC /* For Power C too */
- X# define __TURBOC__
- X#endif /* __POWERC */
- X#ifdef __TURBOC__
- X# ifndef MSDOS
- X# define MSDOS
- X# endif /* !MSDOS */
- X#endif /* __TURBOC__ */
- X
- X
- X/* Use prototypes and ANSI libraries if Microsoft or Borland C */
- X#ifdef MSDOS
- X# ifndef PROTO
- X# define PROTO
- X# endif /* !PROTO */
- X# define MODERN
- X#endif /* MSDOS */
- X
- X
- X/* Turn off prototypes if requested */
- X#ifdef NOPROTO
- X# ifdef PROTO
- X# undef PROTO
- X# endif /* PROTO */
- X#endif /* NOPROT */
- X
- X
- X/* Used to remove arguments in function prototypes for non-ANSI C */
- X#ifdef PROTO
- X# define OF(a) a
- X#else /* !PROTO */
- X# define OF(a) ()
- X#endif /* ?PROTO */
- X
- X
- X/* Allow far and huge allocation for small model (Microsoft C or Turbo C) */
- X#ifdef MSDOS
- X# ifdef __TURBOC__
- X# include <alloc.h>
- X# else /* !__TURBOC__ */
- X# include <malloc.h>
- X# define farmalloc _fmalloc
- X# define farfree _ffree
- X# endif /* ?__TURBOC__ */
- X#else /* !MSDOS */
- X# define huge
- X# define far
- X# define near
- X# define farmalloc malloc
- X# define farfree free
- X#endif /* ?MSDOS */
- X
- X
- X/* Define MSVMS if either MSDOS or VMS defined */
- X#ifdef MSDOS
- X# define MSVMS
- X#else /* !MSDOS */
- X# ifdef VMS
- X# define MSVMS
- X# endif /* VMS */
- X#endif /* ?MSDOS */
- X
- X
- X/* Define void, voidp, and extent (size_t) */
- X#include <stdio.h>
- X#ifdef MODERN
- X# ifndef M_XENIX
- X# include <stddef.h>
- X# endif /* !M_XENIX */
- X# include <stdlib.h>
- X typedef size_t extent;
- X typedef void voidp;
- X#else /* !MODERN */
- X typedef unsigned int extent;
- X# define void int
- X typedef char voidp;
- X#endif /* ?MODERN */
- X
- X/* Get types and stat */
- X#ifdef VMS
- X# include <types.h>
- X# include <stat.h>
- X#else /* !VMS */
- X# include <sys/types.h>
- X# include <sys/stat.h>
- X#endif /* ?VMS */
- X
- X
- X/* Cheap fix for unlink on VMS */
- X#ifdef VMS
- X# define unlink delete
- X#endif /* VMS */
- X
- X
- X/* For Pyramid */
- X#ifdef pyr
- X# define strrchr rindex
- X# define ZMEM
- X#endif /* pyr */
- X
- X
- X/* File operations--use "b" for binary if allowed */
- X#ifdef MODERN
- X# define FOPR "rb"
- X# define FOPM "r+b"
- X# define FOPW "w+b"
- X#else /* !MODERN */
- X# define FOPR "r"
- X# define FOPM "r+"
- X# define FOPW "w+"
- X#endif /* ?MODERN */
- X
- X
- X/* Fine tuning */
- X#ifndef MSDOS
- X# define BSZ 8192 /* Buffer size for files */
- X#else /* !MSDOS */
- X# define BSZ 4096 /* Keep precious NEAR space */
- X /* BSZ can't be 8192 even for compact model because of 64K limitation
- X * in im_lmat.c. If you run out of memory when processing a large number
- X * files, use the compact model and reduce BSZ to 2048 here and in
- X * im_lm.asm.
- X */
- X#endif /* ?MSDOS */
- X
- X/* end of tailor.h */
- X
- X#ifdef MODERN
- X# include <string.h>
- X#else /* !MODERN */
- X voidp *malloc();
- X long atol();
- X char *strcpy();
- X char *strrchr();
- X#endif /* ?MODERN */
- X
- X/* Library functions not in (most) header files */
- char *mktemp OF((char *));
- int unlink OF((char *));
- X
- X#ifdef MSDOS /* Use binary mode for binary files */
- X# include <io.h>
- X# include <fcntl.h>
- X#endif /* MSDOS */
- X
- X
- X#define LNSZ 1025 /* size of line buffer */
- X
- typedef unsigned long ulg; /* 32-bit unsigned integer */
- X
- typedef struct { /* associates a CRC with a file */
- X FILE *f; /* pointer to associated file stream */
- X ulg c; /* CRC register */
- X ulg b; /* four byte buffer */
- X int n; /* buffer count */
- X} cfile;
- X
- X
- X/* Function prototypes */
- X#ifdef MODERN
- X void err(int, char *);
- X cfile *chook(FILE *);
- X char *nopath(char *);
- X void newship(void);
- X void endship(int);
- X void newline(char *);
- X void ship(char *, FILE *);
- X void mkinv(void);
- X void decode(unsigned char *, cfile *);
- X void unship(char **, int, int);
- X void help(void);
- X void main(int, char **);
- X#endif /* MODERN */
- X
- X
- X
- X/* Globals for ship() */
- char sname[9]; /* current ship file name */
- XFILE *sfile; /* current ship file */
- ulg slns; /* number of lines written to ship file */
- ulg slmax; /* maximum number of lines per ship file */
- int fast; /* true for arithmetic coding, else base 85 */
- int mail; /* true if mailing */
- char mpspc[9]; /* prealloced space for prefix */
- char *mprefix = mpspc; /* identification for this mailing */
- char *mdest; /* mail destination */
- char mname[10]; /* temporary file name if mailing */
- ulg ccnt; /* count of bytes read or written */
- int noisy = 1; /* false to inhibit informational messages */
- X
- X
- X
- X/* Errors */
- X#define SE_ARG 1
- X#define SE_FIND 2
- X#define SE_NONE 3
- X#define SE_PART 4
- X#define SE_FORM 5
- X#define SE_CONT 6
- X#define SE_CRC 7
- X#define SE_MAIL 8
- X#define SE_OVER 9
- X#define SE_FULL 10
- X#define SE_MANY 11
- X#define SE_MEM 12
- char *errors[] = {
- X /* 1 */ "invalid argument ",
- X /* 2 */ "could not find ",
- X /* 3 */ "no files received",
- X /* 4 */ "unfinished file ",
- X /* 5 */ "invalid ship format in ",
- X /* 6 */ "wrong sequence for ",
- X /* 7 */ "CRC check failed on ",
- X /* 8 */ "mail command failed: ",
- X /* 9 */ "attempted to overwrite ",
- X /* 10 */ "could not write to ",
- X /* 11 */ "too many output files!",
- X /* 12 */ "out of memory"
- X};
- X
- X
- X/* Set of 86 characters used for the base 85 digits (last one not used), and
- X the 86 character arithmetic coding. Selected to be part of both the ASCII
- X printable characters, and the common EBCDIC printable characters whose
- X ASCII translations are universal. */
- unsigned char safe[] = {
- X '{','"','#','$','%','&','\'','(',')','*','+',',','-','.','/',
- X '0','1','2','3','4','5','6','7','8','9',':',';','<','=','>','?','@',
- X 'A','B','C','D','E','F','G','H','I','J','K','L','M',
- X 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z','_',
- X 'a','b','c','d','e','f','g','h','i','j','k','l','m',
- X 'n','o','p','q','r','s','t','u','v','w','x','y','z','}'};
- X
- X#define LOWSZ (sizeof(safe)-64) /* low set size for fast coding */
- X
- X/* Special replacement pairs--if first of each pair is received, it is
- X treated like the second member of the pair. You're probably
- X wondering why. The first pair is for compatibility with an
- X earlier version of ship that used ! for the base 85 zero digit.
- X However, there exist ASCII-EBCDIC translation tables that don't
- X know about exclamation marks. The second set has mysterious
- X historical origins that are best left unspoken ... */
- unsigned char aliases[] = {'!','{','|','+',0};
- X
- X/* Inverse of safe[], filled in by mkinv() */
- unsigned char invsafe[256];
- X
- X/* Table of CRC-32's of all single byte values (made by makecrc.c) */
- ulg crctab[] = {
- X 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
- X 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
- X 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
- X 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
- X 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
- X 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
- X 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
- X 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
- X 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
- X 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
- X 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
- X 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
- X 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
- X 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
- X 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
- X 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
- X 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
- X 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
- X 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
- X 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
- X 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
- X 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
- X 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
- X 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
- X 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
- X 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
- X 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
- X 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
- X 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
- X 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
- X 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
- X 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
- X 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
- X 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
- X 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
- X 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
- X 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
- X 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
- X 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
- X 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
- X 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
- X 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
- X 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
- X 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
- X 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
- X 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
- X 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
- X 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
- X 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
- X 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
- X 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
- X 0x2d02ef8dL
- X};
- X
- X/* Macro to update the CRC shift register one byte at a time */
- X#define CRC(c,b) (crctab[((int)(c)^(int)(b))&0xff]^((c)>>8))
- X
- X
- char *errname = "ship error";
- char *warname = "ship warning";
- X
- void err(n, m)
- int n; /* error number */
- char *m; /* additional error information */
- X{
- X if (n == SE_FIND || n == SE_FULL)
- X perror(errname);
- X fputs(errname, stderr);
- X fputs(": ", stderr);
- X fputs(errors[n - 1], stderr);
- X fputs(m, stderr);
- X putc('\n', stderr);
- X if (*mname)
- X unlink(mname);
- X#ifdef VMS
- X exit(0);
- X#else /* !VMS */
- X exit(n);
- X#endif /* ?VMS */
- X}
- X
- X
- cfile *chook(f)
- XFILE *f; /* file stream */
- X/* Inherit the file stream structure and add a CRC and buffer for appending
- X a CRC on reads and checking the CRC on writes. Return a pointer to the
- X cfile structure, or NULL if the malloc() failed. Also, if MSDOS, set the
- X file mode to binary to avoid LF<->CRLF conversions. */
- X{
- X cfile *c; /* allocated cfile structure */
- X
- X#ifdef MSDOS
- X /* Set file mode to binary for MSDOS systems */
- X setmode(fileno(f), O_BINARY);
- X#endif /* MSDOS */
- X
- X /* Allocate and fill structure */
- X if ((c = (cfile *)malloc(sizeof(cfile))) != NULL)
- X {
- X c->f = f; /* file stream */
- X c->b = 0; /* empty fifo (for output) */
- X c->c = 0xffffffffL; /* preload CRC register */
- X c->n = 0; /* fifo is empty (output) or */
- X } /* no CRC bytes given (input) */
- X return c;
- X}
- X
- X
- X
- X/* cgetc(x)--like getc(f), but appends a 32-bit CRC to the end of the stream.
- X Return the byte read (the last four of which will be the CRC) or EOF. */
- X#define cgete(x) (x->n==4?EOF:(x->c=x->n++?x->c>>8:~x->c,(int)x->c&0xff))
- X#define cgetc(x) (x->n==0&&(b=getc(x->f))!=EOF?(ccnt++,x->c=CRC(x->c,b),b):cgete(c))
- X
- X
- X/* cputc(d,x)--like putc(d,f), but delays four bytes and computes a CRC.
- X x is a cfile *, and d is expected to be an ulg. */
- X#define cputf(x) (int)(x->c=CRC(x->c,x->b),putc((int)x->b&0xff,x->f),ccnt++)
- X#define cputc(d,x) (x->n!=4?x->n++:cputf(x),x->b=(x->b>>8)+((ulg)(d)<<24))
- X
- X
- char *nopath(p)
- char *p; /* full file name */
- X/* Extract just the name of file--remove and subdirectories or devices */
- X{
- X#ifdef MSDOS
- X char *q = "/\\:"; /* MSDOS delimiters */
- X#else /* !MSDOS */
- X#ifdef VMS
- X char *q = "]:"; /* VMS delimiters */
- X#else /* !VMS */
- X char *q = "/"; /* Unix delimiter */
- X#endif /* ?VMS */
- X#endif /* ?MSDOS */
- X char *r; /* result of strrchr() */
- X
- X while (*q)
- X if ((r = strrchr(p, *q++)) != NULL)
- X p = r + 1;
- X return p;
- X}
- X
- X
- void newship()
- X/* Open up a new ship file to write to */
- X{
- X int i; /* scans down name to increment */
- X
- X for (i = 7; i > 3; i--)
- X if (++sname[i] > '9')
- X sname[i] = '0';
- X else
- X break;
- X if (i == 3)
- X err(SE_MANY, "");
- X if ((sfile = fopen(mail ? mktemp(strcpy(mname, TMPNAME)) : sname,
- X "w")) == NULL)
- X err(SE_FULL, mail ? mname : sname);
- X slns = 0;
- X}
- X
- X
- void endship(e)
- int e; /* true if ending the last ship file */
- X/* Finish off current ship file */
- X{
- X char *s; /* malloc'd space for mail command */
- X
- X if (ferror(sfile) || fclose(sfile))
- X err(SE_FULL, mail ? mname : sname);
- X if (mail)
- X {
- X if ((s = malloc(strlen(MAILCMD)- 5*2 + strlen(mprefix) + strlen(sname) +
- X (e ? 7 : 0) + strlen(mdest) + strlen(mname) + 1)) == NULL)
- X err(SE_MEM, "");
- X#ifdef VMS
- X sprintf(s, MAILCMD, mname, mprefix, sname, e ? " (last)" : "", mdest);
- X if (!system(s)) /* this string fits on one line */
- X err(SE_MAIL, "system() call is not supported on this machine");
- X#else /* !VMS */
- X sprintf(s, MAILCMD, mprefix, sname, e ? " (last)" : "", mdest, mname);
- X if (system(s))
- X err(SE_MAIL, s);
- X#endif /* ?VMS */
- X free((voidp *)s);
- X unlink(mname);
- X *mname = 0;
- X }
- X}
- X
- X
- void newline(p)
- char *p; /* name of the input file */
- X/* Add a new line inside a ship file, possibly cut the file */
- X{
- X putc('\n', sfile);
- X slns++;
- X if (slmax && slns >= slmax - 2)
- X {
- X putc('$', sfile);
- X if (fast)
- X fputs(" f", sfile);
- X fputs("\nmore\n", sfile);
- X endship(0);
- X newship();
- X fprintf(sfile, "$%s\ncont %lu %s\n", fast ? " f" : "", ccnt, nopath(p));
- X slns += 2;
- X }
- X}
- X
- X
- X/* Macro to avoid leading dots. It assumes i==0 at the beginning of a line
- X and that b is an available int. c is only evaluated once. */
- X#define sputc(c,f) (i==0?((b=(c))=='.'?putc(' ',f):0,putc(b,f)):putc(c,f))
- X
- X
- void ship(p, f)
- char *p; /* name of the input file */
- XFILE *f; /* input file */
- X/* Encode the binary file f. */
- X{
- X int b; /* character just read */
- X cfile *c; /* checked file stream */
- X int i; /* how much is written on line so far */
- X int j; /* how much is in bit buffer */
- X
- X /* Set up output file if needed */
- X if ((mail || slmax) && sfile == stdout)
- X {
- X strcpy(sname, "part0000");
- X newship();
- X }
- X
- X /* Write header */
- X if ((c = chook(f)) == NULL)
- X err(SE_MEM, "");
- X ccnt = 0;
- X if (slmax && slns >= slmax - 5)
- X {
- X endship(0);
- X newship();
- X }
- X fprintf(sfile, "$%s\nship %s\n", fast ? " f" : "", nopath(p));
- X slns += 2;
- X
- X /* Encode the file, writing to sfile */
- X if (fast)
- X {
- X int d; /* accumulates bits (never more than 14) */
- X
- X d = j = i = 0;
- X while ((b = cgetc(c)) != EOF)
- X {
- X d |= b << j;
- X j += 8;
- X if ((d & 0x3f) >= LOWSZ)
- X {
- X sputc((int)(safe[(d & 0x3f) + LOWSZ]), sfile);
- X d >>= 6;
- X j -= 6;
- X }
- X else
- X {
- X sputc((int)(safe[(d & 0x3f) + (d & 0x40 ? LOWSZ : 0)]), sfile);
- X d >>= 7;
- X j -= 7;
- X }
- X if (++i == 79)
- X {
- X newline(p);
- X i = 0;
- X }
- X if (j >= 6 && (d & 0x3f) >= LOWSZ)
- X {
- X sputc((int)(safe[(d & 0x3f) + LOWSZ]), sfile);
- X d >>= 6;
- X j -= 6;
- X if (++i == 79)
- X {
- X newline(p);
- X i = 0;
- X }
- X }
- X else if (j >= 7)
- X {
- X sputc((int)(safe[(d & 0x3f) + (d & 0x40 ? LOWSZ : 0)]), sfile);
- X d >>= 7;
- X j -= 7;
- X if (++i == 79)
- X {
- X newline(p);
- X i = 0;
- X }
- X }
- X }
- X free((voidp *)c);
- X
- X /* Write leftover bits */
- X if (j)
- X {
- X sputc((int)(safe[d + (d < LOWSZ ? 0 : LOWSZ)]), sfile);
- X putc('\n', sfile);
- X slns++;
- X }
- X else if (i)
- X {
- X putc('\n', sfile);
- X slns++;
- X }
- X }
- X else
- X {
- X ulg d; /* accumulates bytes */
- X
- X d = j = i = 0;
- X while ((b = cgetc(c)) != EOF)
- X {
- X d += ((ulg)b) << j;
- X if ((j += 8) == 32)
- X {
- X sputc((int)(safe[(int)(d % 85)]), sfile); d /= 85;
- X putc((int)(safe[(int)(d % 85)]), sfile); d /= 85;
- X putc((int)(safe[(int)(d % 85)]), sfile); d /= 85;
- X putc((int)(safe[(int)(d % 85)]), sfile); d /= 85;
- X putc((int)(safe[(int)d]), sfile);
- X if (++i == 15) /* each line is <= 75 characters */
- X {
- X newline(p);
- X i = 0;
- X }
- X d = j = 0;
- X }
- X }
- X free((voidp *)c);
- X
- X /* Write leftover data */
- X if (j)
- X {
- X j >>= 3;
- X sputc((int)(safe[(int)(d % 85)]), sfile);
- X while (j--)
- X {
- X d /= 85;
- X putc((int)(safe[(int)(d % 85)]), sfile);
- X }
- X putc('\n', sfile);
- X slns++;
- X }
- X else if (i)
- X {
- X putc('\n', sfile);
- X slns++;
- X }
- X }
- X putc('$', sfile);
- X if (fast)
- X fputs(" f", sfile);
- X fputs("\nend\n", sfile);
- X slns += 2;
- X if (ferror(sfile) || fflush(sfile))
- X err(SE_FULL, mail ? mname : sname);
- X if (noisy)
- X fprintf(stderr, "%s shipped\n", p);
- X}
- X
- X
- void mkinv()
- X/* Build invsafe[], the inverse of safe[]. */
- X{
- X int i;
- X
- X for (i = 0; i < 256; i++)
- X invsafe[i] = 127;
- X for (i = 0; i < sizeof(safe); i++)
- X invsafe[safe[i]] = (char)i;
- X for (i = 0; aliases[i]; i += 2)
- X invsafe[aliases[i]] = invsafe[aliases[i + 1]];
- X}
- X
- X
- unsigned int decb; /* bit buffer for decode */
- unsigned int decn; /* number of bits in decb */
- X
- void decode(s, c)
- unsigned char *s; /* data to decode */
- cfile *c; /* binary output file */
- X/* Decode s, a string of base 85 digits or, if fast is true, a string of safe
- X characters generated arithmetically, into its binary equivalent, writing
- X the result to c, using cputc(). */
- X{
- X int b; /* state of line loop, next character */
- X int k; /* counts bits or digits read */
- X /* powers of 85 table for decoding */
- X static ulg m[] = {1L,85L,85L*85L,85L*85L*85L,85L*85L*85L*85L};
- X
- X if (fast)
- X {
- X unsigned int d; /* disperses bits */
- X
- X d = decb;
- X k = decn;
- X while ((b = *s++) != 0)
- X if ((b = invsafe[b]) < sizeof(safe))
- X {
- X if (b < LOWSZ)
- X {
- X d |= b << k;
- X k += 7;
- X }
- X else if ((b -= LOWSZ) < LOWSZ)
- X {
- X d |= (b + 0x40) << k;
- X k += 7;
- X }
- X else
- X {
- X d |= b << k;
- X k += 6;
- X }
- X if (k >= 8)
- X {
- X cputc(d, c);
- X d >>= 8;
- X k -= 8;
- X }
- X }
- X decb = d;
- X decn = k;
- X }
- X else
- X {
- X ulg d; /* disperses bytes */
- X
- X d = k = 0;
- X while ((b = *s++) != 0)
- X if ((b = invsafe[b]) < 85)
- X {
- X d += m[k] * b;
- X if (++k == 5)
- X {
- X cputc(d, c); d >>= 8;
- X cputc(d, c); d >>= 8;
- X cputc(d, c); d >>= 8;
- X cputc(d, c);
- X d = k = 0;
- X }
- X }
- X if (--k > 0)
- X {
- X while (--k)
- X {
- X cputc(d, c);
- X d >>= 8;
- X }
- X cputc(d, c);
- X }
- X }
- X}
- X
- X
- void unship(v, g, o)
- char **v; /* arguments */
- int g; /* number of arguments */
- int o; /* overwrite flag */
- X/* Extract from the files named in the arguments the files that were
- X encoded by ship. If an argument is "-", then stdin is read. */
- X{
- X int b; /* state of line loop */
- X cfile *c; /* output binary file */
- X FILE *f; /* output file */
- X char *h; /* name of current ship file */
- X char l[LNSZ]; /* line buffer on input */
- X int n; /* next argument to use for input */
- X char *p; /* modifies line buffer */
- X char *q; /* scans continuation line */
- X char *r; /* name of output binary file */
- X FILE *s; /* current ship file */
- X int z; /* true if zero files received */
- X
- X /* Build inverse table */
- X mkinv();
- X
- X /* No input or output files initially */
- X s = NULL;
- X c = NULL;
- X h = r = NULL;
- X
- X /* Loop on input files' lines */
- X z = 1; /* none received yet */
- X n = 0; /* start with file zero */
- X b = 2; /* not in body yet */
- X while (1) /* return on end of last file */
- X {
- X /* Get next line from list of files */
- X while (s == NULL || fgets(l, LNSZ, s) == NULL)
- X {
- X if (s != NULL)
- X fclose(s);
- X if (n >= g)
- X {
- X if (c != NULL)
- X err(SE_PART, r);
- X else if (z)
- X err(SE_NONE, "");
- X return;
- X }
- X if (v[n][0] == '-')
- X if (v[n][1])
- X err(SE_ARG, v[n]);
- X else
- X {
- X h = "stream stdin";
- X s = stdin;
- X }
- X else
- X {
- X h = v[n];
- X if ((s = fopen(h, "r")) == NULL)
- X err(SE_FIND, h);
- X }
- X n++;
- X b &= ~1; /* not in middle of line */
- X }
- X
- X /* Strip control characters and leading blank space, if any */
- X for (q = l; *q && *q <= ' ' && *q != '\n'; q++)
- X ;
- X for (p = l; *q; q++)
- X if (*q >= ' ' || *q == '\n')
- X *p++ = *q;
- X *p = 0;
- X
- X /* Based on current state, end or start on terminator. States are:
- X b == 0: at start of body or body terminator line
- X b == 1: in middle of body line
- X b == 2: at start of non-body line
- X b == 3: in middle of non-body line
- X b == 4: at information line
- X */
- X switch (b)
- X {
- X case 0:
- X if ((!fast && strcmp(l, "$\n") == 0) ||
- X (fast && strcmp(l, "$ f\n") == 0))
- X {
- X b = 4;
- X break;
- X }
- X /* fall through to case 1 */
- X case 1:
- X decode((unsigned char *)l, c);
- X b = l[strlen(l) - 1] != '\n';
- X break;
- X case 2:
- X if (strcmp(l, "$\n") == 0 || strcmp(l, "$ f\n") == 0)
- X {
- X fast = l[1] == ' ';
- X b = 4;
- X break;
- X }
- X /* fall through to case 3 */
- X case 3:
- X b = l[strlen(l)-1] == '\n' ? 2 : 3;
- X break;
- X case 4:
- X /* Possible information lines are ship, more, cont, and end */
- X if (l[b = strlen(l) - 1] != '\n')
- X err(SE_FORM, h);
- X l[b] = 0;
- X if (strncmp(l, "ship ", 5) == 0)
- X {
- X /* get name, open new output file */
- X if (c != NULL)
- X err(SE_FORM, h);
- X if ((r = malloc(b - 4)) == NULL)
- X err(SE_MEM, "");
- X strcpy(r, l + 5);
- X if (strcmp(r, "-") == 0)
- X f = stdout;
- X#ifndef VMS /* shouldn't have explicit version #, so VMS won't overwrite */
- X else if (!o && (f = fopen(r, "r")) != NULL)
- X {
- X fclose(f);
- X err(SE_OVER, r);
- X }
- X#endif /* !VMS */
- X else if ((f = fopen(r, "w")) == NULL)
- X err(SE_FULL, r);
- X if ((c = chook(f)) == NULL)
- X err(SE_MEM, "");
- X b = decb = decn = 0;
- X ccnt = 0;
- X }
- X else if (strcmp(l, "more") == 0)
- X {
- X /* check if currently writing */
- X if (c == NULL)
- X err(SE_FORM, h);
- X b = 2;
- X }
- X else if (strncmp(l, "cont ", 5) == 0)
- X {
- X /* check name and file offset */
- X if (c == NULL)
- X err(SE_FORM, h);
- X for (q = l + 5; *q && *q != ' '; q++)
- X ;
- X if (*q == 0 || atol(l + 5) != ccnt + 4 + (decn != 0) ||
- X strcmp(q + 1, r))
- X err(SE_CONT, r);
- X b = 0;
- X }
- X else if (strcmp(l, "end") == 0)
- X {
- X /* check crc, close output file */
- X if (c == NULL)
- X err(SE_FORM, h);
- X if (c->n != 4 || c->b != ~c->c)
- X err(SE_CRC, r);
- X if (ferror(c->f) || fclose(c->f))
- X err(SE_FULL, r);
- X if (noisy)
- X fprintf(stderr, "%s received\n", r);
- X z = 0;
- X free((voidp *)c);
- X c = NULL;
- X b = 2;
- X }
- X else
- X {
- X for (q = l; *q && *q != ' '; q++)
- X ;
- X *q = 0;
- X fprintf(stderr, "%s: unsupported keyword '%s' ignored\n", warname, l);
- X b = 4;
- X }
- X break;
- X }
- X }
- X}
- X
- X
- void help()
- X{
- X int i;
- X static char *text[] = {
- X"Usage:",
- X" ship [-f] [-q] [-nnn] [-m address] [-s subject] files...",
- X"",
- X" ships the files to stdout. -m sends the output via the mailer to",
- X" address. -nnn splits the output into pieces of nnnK bytes or less.",
- X" if -nnn is used without -m, the output goes to the files partxxxx,",
- X" where xxxx is 0001, 0002, etc. If -0 is specified, the output goes",
- X" entirely to the file part0001. -f uses a fast method with slightly",
- X" less performance. If no files are given, stdin is used. The special",
- X" filename '-' also takes input from stdin. Files shipped from stdin",
- X" are unshipped to stdout. This can be used to document a shipment.",
- X" When mailing, -s gives a subject line prefix. -q inhibits messages.",
- X"",
- X" ship -u [-o] [-q] files...",
- X" unship [-o] [-q] files...",
- X"",
- X" extracts the contents of the mail messages in files... -o allows",
- X" existing files to be overwritten. -u is implied if the name of the",
- X" executable is unship. If no files are given, the input is from",
- X" stdin. If any of the files were shipped from stdin, then they are",
- X" extracted to stdout."
- X };
- X
- X puts(SHIPVER);
- X for (i = 0; i < sizeof(text)/sizeof(char *); i++)
- X {
- X printf(text[i]);
- X putchar('\n');
- X }
- X exit(0);
- X}
- X
- X
- void main(argc, argv)
- int argc; /* number of arguments */
- char **argv; /* table of argument strings */
- X{
- X FILE *f; /* input file */
- X char *p; /* temporary variable */
- X int o; /* overwrite flag */
- X int r; /* temporary variable */
- X int s; /* true if no names given */
- X
- X /* No temporary file yet (for err()) */
- X *mname = 0;
- X
- X /* No subject prefix yet */
- X *mprefix = 0;
- X
- X /* See if help requested */
- X if (argc > 1 && (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "-?") == 0))
- X help();
- X
- X /* Unship */
- X if ((p = strrchr(argv[0], PATHCUT)) == NULL)
- X p = argv[0];
- X else
- X p++;
- X r = 0; /* (make some compilers happier) */
- X if ((r = strncmp(p, "unship", 6)) == 0 ||
- X (r = strncmp(p, "UNSHIP", 6)) == 0 ||
- X (argc > 1 && strcmp(argv[1], "-u") == 0))
- X {
- X errname = "unship error";
- X warname = "unship warning";
- X r = r ? 2 : 1; /* next arg */
- X o = 0; /* disallow overwriting */
- X if (r < argc && strcmp(argv[r], "-o") == 0)
- X {
- X r++;
- X o = 1; /* allow overwriting */
- X }
- X if (r < argc && strcmp(argv[r], "-q") == 0)
- X {
- X r++;
- X noisy = 0; /* inhibit messages */
- X }
- X if (r < argc)
- X unship(argv + r, argc - r, o); /* unship files in args */
- X else
- X {
- X char *a[1]; /* short list of names (one) */
- X
- X a[0] = "-";
- X unship(a, 1, o); /* no args--do stdin */
- X }
- X }
- X
- X /* Ship */
- X else
- X {
- X mail = 0; /* not mailing */
- X fast = 0; /* use base 85 encoding */
- X s = 1; /* no names given yet */
- X strcpy(sname, "-"); /* output to stdout */
- X sfile = stdout;
- X slns = slmax = 0;
- X for (r = 1; r < argc; r++) /* go through args */
- X if (argv[r][0] == '-') /* option or stdin */
- X if (argv[r][1]) /* option */
- X {
- X if (argv[r][1] == 'm') /* mail output */
- X {
- X mail = 1;
- X mdest = NULL; /* next arg is mail address */
- X }
- X else if (argv[r][1] == 's') /* next arg is subject prefix */
- X mprefix = NULL;
- X else if (argv[r][1] == 'f') /* fast arithmetic encoding */
- X fast = 1;
- X else if (argv[r][1] == 'q') /* quiet operation */
- X noisy = 0;
- X else /* option is number of lines */
- X {
- X /* Check numeric option */
- X for (p = argv[r] + 1; *p; p++)
- X if (*p < '0' || *p > '9')
- X break;
- X if (*p || slmax)
- X err(SE_ARG, argv[r]);
- X
- X /* Zero means infinity, else convert */
- X if ((slmax = atol(argv[r] + 1)) == 0)
- X slmax = -1L;
- X else
- X {
- X long b;
- X
- X b = slmax * 1000L;
- X slmax = (int)(b / (fast ? 81 : 77));
- X /* Note: five of the lines aren't that long, but that
- X leaves some slack for mail headers, etc. Also, note
- X that we conservatively assume 1000 bytes/K and two
- X bytes per new line. */
- X }
- X }
- X }
- X else /* input file is stdin */
- X {
- X if (mail && mdest == NULL)
- X err(SE_ARG, "- (no mail destination given)");
- X s = 0;
- X if (mail && !*mprefix)
- X strcpy(mprefix, "(stdin)");
- X ship("-", stdin);
- X }
- X else /* not option or stdin */
- X if (mail && mdest == NULL) /* arg is mail address */
- X mdest = argv[r];
- X else if (mprefix == NULL) /* arg is subject prefix */
- X mprefix = argv[r];
- X else /* arg is file to ship */
- X {
- X s = 0;
- X if ((f = fopen(argv[r], "r")) == NULL)
- X err(SE_FIND, argv[r]);
- X if (mail && !*mprefix)
- X {
- X int i;
- X
- X for (i = 0, p = nopath(argv[r]); i < 8 && *p; p++)
- X if ((*p >= '0' && *p <= '9') || (*p >= 'A' && *p <= 'Z') ||
- X (*p >= 'a' && *p <= 'z') || *p == '.' || *p == '_')
- X mprefix[i++] = *p;
- X mprefix[i] = 0;
- X }
- X ship(argv[r], f);
- X fclose(f);
- X }
- X if (s) /* no names--act as filter */
- X if (mail && mdest == NULL)
- X err(SE_ARG, "-m (no mail destination given)");
- X else if (mprefix == NULL)
- X err(SE_ARG, "-s (no subject prefix given)");
- X else
- X {
- X if (mail && !*mprefix)
- X strcpy(mprefix, "(stdin)");
- X ship("-", stdin);
- X }
- X endship(1); /* clean up */
- X if (noisy && (mail || slmax))
- X fprintf(stderr, "file%s%s %s\n",
- X strcmp("part0001", sname) ? "s part0001.." : " ", sname,
- X mail ? "mailed" : "written");
- X }
- X
- X /* Done */
- X exit(0);
- X}
- END_OF_FILE
- if test 38393 -ne `wc -c <'ship.c'`; then
- echo shar: \"'ship.c'\" unpacked with wrong size!
- fi
- # end of 'ship.c'
- fi
- echo shar: End of archive 5 \(of 7\).
- cp /dev/null ark5isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 7 archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-